using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Rhizome.Contract;
using Rhizome.Contract.Visitor;

namespace Rhizome.Model
{
	/// <summary>
	/// XAML "macro" class (ActiveTimerTrigger + Increment)
	/// </summary>
	/// <typeparam name="TValue">Incremented property type</typeparam>
	/// <typeparam name="TStep">Increment step type</typeparam>
	/// <typeparam name="TIncementAction">Increment action class type</typeparam>
	public abstract class ActiveCounterBase<TValue, TStep, TIncementAction> : ActiveTimerTrigger 
		where TIncementAction : Increment<TValue, TStep>, new()
	{
		public string Property { get; set; }
		public TStep Step { get; set; }
		public bool CacheValue { get; set; }

		private TIncementAction _action;

		#region Overrides of ActiveTriggerBase<object>

		public override IAction Action
		{
			[DebuggerStepThrough]
			get { return _action ?? (_action = CreateIncrementAction()); }
			[DebuggerStepThrough]
			set {throw new NotSupportedException("CounterBase.Action can not be set manually"); }
		}

		#endregion

		private TIncementAction CreateIncrementAction()
		{
			return new TIncementAction {Step = Step, Property = Property, CacheValue = CacheValue, Parent = this};
		}

		#region Overrides of RhizomeElement

		public override IEnumerable<IElement> GetElements()
		{
			return base.GetElements().Concat(new[] {(IElement) Action});
		}

		#endregion
	}

	public sealed class Counter : ActiveCounterBase<int, int, Increment>
	{
	}

	public sealed class DoubleCounter : ActiveCounterBase<double, double , IncDouble>
	{
	}

	public sealed class TimeSpanCounter : ActiveCounterBase<TimeSpan, TimeSpan, IncTimeSpan>
	{
	}
}